from __future__ import division

import logging, unittest, time, tempfile, os

import numpy.testing, scipy.integrate, scipy.constants

import kinetics_opt, kinetics_opt_main, retraction_unfolding_filter, test_util

logger = logging.getLogger("kinetics_opt_main_test")
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.INFO)

cs0 = retraction_unfolding_filter.CurveStretch(
    "cs0", 0.0786153, 2.18e-06, [
        retraction_unfolding_filter.RetractionPeak(
            1.241e-07, 3.921e-11, 3.037e-10, 1.147e-07),
        retraction_unfolding_filter.RetractionPeak(
            1.028e-07, 2.280e-11, 2.760e-10, 9.487e-08),
        retraction_unfolding_filter.RetractionPeak(
            8.345e-08, 2.267e-11, 2.006e-10, 7.534e-08),
        retraction_unfolding_filter.RetractionPeak(
            6.362e-08, 1.234e-12, 2.920e-10, 6.069e-08)],
    1.703e-11)

cs1 = retraction_unfolding_filter.CurveStretch(
    "cs1", 0.0786153, 2.18e-06, [
        retraction_unfolding_filter.RetractionPeak(
            7.90e-08, 6.066e-12, 2.410e-10, 7.236e-08),
        retraction_unfolding_filter.RetractionPeak(
            6.076e-08, 4.809e-12, 2.544e-10, 5.680e-08),
        retraction_unfolding_filter.RetractionPeak(
            4.163e-08, 1.146e-14, 1.519e-10, 3.788e-08)],
    1.774e-11)

def make_cs0_file():
    return make_cs_file(cs0)

def make_cs1_file():
    return make_cs_file(cs1)

def make_cs_file(cs):
    fd, temp_path = tempfile.mkstemp()
    with open(temp_path, 'wb') as out_file:
        out_file.write(repr(cs) + "\n")
    os.close(fd)
    return temp_path


class KineticsOptMainTest(unittest.TestCase):

    def test_mle(self):
        temp_path = make_cs0_file()
        actual = kinetics_opt_main.main([
                "--curve_stretch_playlists", temp_path,
                "--fit_methods", "mle",
                "--diffuse_distribution=normal",
                "--diffuse_half_support_units=60",
                "--seeds", "0"])
        os.remove(temp_path)
        expected = ([[[0, 1, 2, 3]]], [], [([(0.015516598233817157253, [ 23.294466, 23.254857, 21.539423, 23.005422]), (6.1644254045965933798e-05, [ 23.680612, 23.589333, 20.184029, 23.462806])], 1.9149747177954356876e-10, 0.0028586732494276483803, [ 23.444604, 23.395007, 21.162469, 23.164018], 7.4321920867760389909e-05, [(0.015765138259939049832, [ 23.113633, 23.131506, 21.68655, 22.859412]), (7.4321920867760389909e-05, [ 23.27132, 23.425886, 20.778959, 23.110481])], 1.8547479706054266819e-10, 0.0044056718277100804304, [ 23.180204, 23.225383, 21.483622, 22.940906])], ())
        test_util.assert_allclose_recursive(actual, expected, rtol=1e-6)

    def test_shared_dx_mle(self):
        temp_path0 = make_cs0_file()
        temp_path1 = make_cs1_file()
        actual = kinetics_opt_main.main([
                "--curve_stretch_playlists", temp_path0, temp_path1,
                "--fit_methods", "shared_dx_mle",
                "--diffuse_distribution=normal",
                "--diffuse_half_support_units=60",
                "--seeds", "0", "0"])
        os.remove(temp_path0)
        os.remove(temp_path1)
        expected = ([[[0, 1, 2, 3]], [[0, 1, 2]]], [], [], (1.7473095644396907379e-10, [(0.0083747968534160743403, [ 23.353697,  23.311078,  21.407895,  23.06601]), (0.079024905272714519056, [ 23.306828,  22.973927,  21.414317])], 1.746974986100510271e-10, [(0.0086365039546735910703, [ 23.148258,  23.178526,  21.592977,  22.900198]), (0.088344108948472825421, [ 23.157281,  22.755526,  21.676073])]))
        test_util.assert_allclose_recursive(actual, expected, rtol=1e-6)


if __name__ == "__main__":
    suite = unittest.TestLoader().loadTestsFromTestCase(KineticsOptMainTest)
    unittest.TextTestRunner(verbosity=2).run(suite)
